// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package resource_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/resource_dao"
	"gitcode.com/lvupclub/lvup-api/dao/user_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/resource_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/user_api"
	"github.com/google/uuid"
)

type ResourceApiImpl struct {
	resource_api.UnimplementedResourceApiServer
}

func (apiImpl *ResourceApiImpl) Create(ctx context.Context, req *resource_api.CreateRequest) (*resource_api.CreateResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_api.CreateResponse{
			Code:   resource_api.CreateResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以创建资料
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &resource_api.CreateResponse{
			Code:   resource_api.CreateResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	resourceId := uuid.NewString()
	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = resource_dao.ResourceInfoDao.Insert(sessCtx, &resource_dao.ResourceInfoDbItem{
			ResourceId:   resourceId,
			ResourceType: req.ResourceType,
			BasicInfo: resource_dao.BasicResourceInfoDbItem{
				Name: req.BasicInfo.Name,
				Desc: req.BasicInfo.Desc,
			},
			OwnerUserId: sessItem.UserId,
			CreateTime:  nowTime,
			UpdateTime:  nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &resource_api.CreateResponse{
			Code:       resource_api.CreateResponse_CODE_OK,
			ResourceId: resourceId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*resource_api.CreateResponse), nil
}

func (apiImpl *ResourceApiImpl) UpdateBasic(ctx context.Context, req *resource_api.UpdateBasicRequest) (*resource_api.UpdateBasicResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_api.UpdateBasicResponse{
			Code:   resource_api.UpdateBasicResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	resourceItem, err := resource_dao.ResourceInfoDao.Get(ctx, req.ResourceId)
	if err != nil {
		return &resource_api.UpdateBasicResponse{
			Code:   resource_api.UpdateBasicResponse_CODE_NO_RESOURCE,
			ErrMsg: "资料库不存在",
		}, nil
	}
	if resourceItem.OwnerUserId != sessItem.UserId {
		return &resource_api.UpdateBasicResponse{
			Code:   resource_api.UpdateBasicResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = resource_dao.ResourceInfoDao.UpdateBasic(sessCtx, req.ResourceId, &resource_dao.BasicResourceInfoDbItem{
			Name: req.BasicInfo.Name,
			Desc: req.BasicInfo.Desc,
		}, nowTime)
		if err != nil {
			return nil, err
		}
		return &resource_api.UpdateBasicResponse{
			Code: resource_api.UpdateBasicResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*resource_api.UpdateBasicResponse), nil
}

func (apiImpl *ResourceApiImpl) Remove(ctx context.Context, req *resource_api.RemoveRequest) (*resource_api.RemoveResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_api.RemoveResponse{
			Code:   resource_api.RemoveResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	resourceItem, err := resource_dao.ResourceInfoDao.Get(ctx, req.ResourceId)
	if err != nil {
		return &resource_api.RemoveResponse{
			Code: resource_api.RemoveResponse_CODE_OK,
		}, nil
	}
	if resourceItem.OwnerUserId != sessItem.UserId {
		return &resource_api.RemoveResponse{
			Code:   resource_api.RemoveResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = resource_dao.ResourceInfoDao.Remove(sessCtx, req.ResourceId)
		if err != nil {
			return nil, err
		}
		if resourceItem.ResourceType == resource_api.RESOURCE_TYPE_RESOURCE_TYPE_CARD {
			err = resource_dao.CardInfoDao.RemoveByResource(sessCtx, req.ResourceId)
			if err != nil {
				return nil, err
			}
			err = resource_dao.CardLinkDao.RemoveByResource(sessCtx, req.ResourceId)
			if err != nil {
				return nil, err
			}
			err = resource_dao.CardStateDao.RemoveByResource(sessCtx, req.ResourceId)
			if err != nil {
				return nil, err
			}
		} else if resourceItem.ResourceType == resource_api.RESOURCE_TYPE_RESOURCE_TYPE_EXAM {
			err = resource_dao.QuestionInfoDao.RemoveByResource(sessCtx, req.ResourceId)
			if err != nil {
				return nil, err
			}
			err = resource_dao.QuestionStateDao.RemoveByResource(sessCtx, req.ResourceId)
			if err != nil {
				return nil, err
			}
		}
		return &resource_api.RemoveResponse{
			Code: resource_api.RemoveResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*resource_api.RemoveResponse), nil
}

func (apiImpl *ResourceApiImpl) List(ctx context.Context, req *resource_api.ListRequest) (*resource_api.ListResponse, error) {
	emptyList := []*resource_api.ResourceInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_api.ListResponse{
			Code:         resource_api.ListResponse_CODE_WRONG_SESSION,
			ErrMsg:       "会话不存在",
			ResourceList: emptyList,
		}, nil
	}

	count, err := resource_dao.ResourceInfoDao.CountByOwner(ctx, sessItem.UserId, req.FilterByResourceType, req.ResourceType, req.FilterByKeyword, req.Keyword)
	if err != nil {
		return nil, err
	}
	resourceItemList, err := resource_dao.ResourceInfoDao.ListByOwner(ctx, sessItem.UserId, req.FilterByResourceType, req.ResourceType, req.FilterByKeyword, req.Keyword, int64(req.Offset), int64(req.Limit))
	if err != nil {
		return nil, err
	}
	//补全用户信息
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, []string{sessItem.UserId})
	if err != nil {
		return nil, err
	}
	//生成结果
	resourceList := []*resource_api.ResourceInfo{}
	for _, resourceItem := range resourceItemList {
		resource := resourceItem.ToResourceInfo()
		if len(userItemList) > 0 {
			resource.OwnerDisplayName = userItemList[0].BasicInfo.DisplayName
			resource.OwnerLogoUri = userItemList[0].BasicInfo.LogoUri
		}
		resourceList = append(resourceList, resource)
	}

	return &resource_api.ListResponse{
		Code:         resource_api.ListResponse_CODE_OK,
		TotalCount:   count,
		ResourceList: resourceList,
	}, nil
}

func (apiImpl *ResourceApiImpl) Get(ctx context.Context, req *resource_api.GetRequest) (*resource_api.GetResponse, error) {
	emptyInfo := &resource_api.ResourceInfo{
		BasicInfo: &resource_api.BasicResourceInfo{},
	}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &resource_api.GetResponse{
			Code:     resource_api.GetResponse_CODE_WRONG_SESSION,
			ErrMsg:   "会话不存在",
			Resource: emptyInfo,
		}, nil
	}
	resourceItem, err := resource_dao.ResourceInfoDao.Get(ctx, req.ResourceId)
	if err != nil {
		return &resource_api.GetResponse{
			Code:     resource_api.GetResponse_CODE_NO_RESOURCE,
			ErrMsg:   "资料库不存在",
			Resource: emptyInfo,
		}, nil
	}
	if resourceItem.OwnerUserId != sessItem.UserId {
		return &resource_api.GetResponse{
			Code:     resource_api.GetResponse_CODE_NO_PERMISSION,
			ErrMsg:   "没有权限",
			Resource: emptyInfo,
		}, nil
	}

	//补全用户信息
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, []string{sessItem.UserId})
	if err != nil {
		return nil, err
	}
	//生成结果
	resource := resourceItem.ToResourceInfo()
	if len(userItemList) > 0 {
		resource.OwnerDisplayName = userItemList[0].BasicInfo.DisplayName
		resource.OwnerLogoUri = userItemList[0].BasicInfo.LogoUri
	}

	return &resource_api.GetResponse{
		Code:     resource_api.GetResponse_CODE_OK,
		Resource: resource,
	}, nil
}
